package org.lzuploader.gui;

import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.lzuploader.gui.listeners.servers.AddSelectionListener;
import org.lzuploader.gui.listeners.servers.CloseSelectionListener;
import org.lzuploader.gui.listeners.servers.ListSelectionListener;
import org.lzuploader.gui.listeners.servers.NameModifyListener;
import org.lzuploader.gui.listeners.servers.ParametersModifyListener;
import org.lzuploader.gui.listeners.servers.RemoveSelectionListener;
import org.lzuploader.gui.listeners.servers.TestSelectionListener;
import org.lzuploader.model.Config;
import org.lzuploader.model.Localization;
import org.lzuploader.model.Server;

/** Class used to display servers dialog.
 * 
 * @author Emmanuel Cron
 *
 */
public class WServers
{
    /** Width of the window. */
    private static final int WINDOW_WIDTH = 500;
    /** Height of the window. */
    private static final int WINDOW_HEIGHT = 245;
    
    /** Logger of this class. */
    private static Log log = LogFactory.getLog(WServers.class);
    /** Localization of this class. */
    private static Localization localization = Localization.getInstance();
    
    /** Shell used to display this window. */
    private Shell shell;
    
    /* COMPONENTS */
    
    /** Text containing the name of the server.
     * This is a random string entered by the user.
     */
    private Text nameText;
    
    /** Text containing the server address. */
    private Text serverText;
    
    /** Text containing the server port to which to connect. */
    private Spinner portText;
    
    /** Text containing the path on the server to look for. */
    private Text pathText;
    
    /** Button used to test a server's parameters. */
    private Button testButton;
    
    /** Button used to add a server to the list. */
    private Button addButton;
    
    /** Button used to remove a server to the list. */
    private Button remove;
    
    /** List displaying the already saved servers. */
    private List list;
    
    /* END OF COMPONENTS */
    
    /** Creates the servers window.
     * Creates the servers window, initializing its controls and various settings
     * @param parent    Parent that called the window.
     */
    public WServers(final Shell parent)
    {
        log.debug("Creating servers window.");
        
        shell = new Shell(parent, SWT.APPLICATION_MODAL + SWT.DIALOG_TRIM);
        shell.setData(this);
        
        Position.centerElement(parent, shell, WINDOW_WIDTH, WINDOW_HEIGHT);
        shell.setText(localization.getString("DIALOG_TITLE_SERVERS"));
        
        log.trace("Opening window.");
        
        shell.open();
        
        // Populating window
        populateWindow();
        
        // Resetting window to defaults
        resetComponents();
    }
    
    /** Resets window components to defaults. */
    public void resetComponents()
    {
        log.debug("Reseting window components.");
        
        if (!nameText.getText().equals(""))
        {
            nameText.setText("");
        }
        if (!serverText.getText().equals(""))
        {
            serverText.setText("");
        }
        if (portText.getSelection() != 80)
        {
            portText.setSelection(80);
        }
        if (!pathText.getText().equals("/LZRoster/"))
        {
            pathText.setText("/LZRoster/");
        }
        
        testButton.setEnabled(true);
        addButton.setEnabled(false);
        remove.setEnabled(false);
        list.deselectAll();
        
        refreshList();
    }
    
    /** Populates the servers window with various controls.
     * Populates the servers window with various controls and sets window properties.
     */
    private void populateWindow()
    {
        log.debug("Populating window.");
        
        log.trace("Creating list.");
        
        list = new List(shell, SWT.SINGLE + SWT.BORDER);
        list.setLocation(10, 10);
        list.setSize(180, 165);
        list.addSelectionListener(new ListSelectionListener());
        
        log.trace("Creating groups.");
        
        final Group add = new Group(shell, SWT.SHADOW_NONE);
        add.setLocation(205, 5);
        add.setSize(280, 170);
        add.setText(localization.getString("GROUP_ADD_SERVER"));
        
        log.trace("Creating labels.");
        
        final Label id = new Label(add, SWT.RIGHT);
        id.setLocation(10, 17);
        id.setSize(50, 20);
        id.setText(localization.getString("LABEL_SERVER_NAME") + ":");
        
        final Label server = new Label(add, SWT.RIGHT);
        server.setLocation(10, 47);
        server.setSize(50, 20);
        server.setText(localization.getString("LABEL_SERVER_SERVER") + ":");
        
        final Label port = new Label(add, SWT.RIGHT);
        port.setLocation(10, 77);
        port.setSize(50, 20);
        port.setText(localization.getString("LABEL_SERVER_PORT") + ":");
        
        final Label path = new Label(add, SWT.RIGHT);
        path.setLocation(10, 107);
        path.setSize(50, 20);
        path.setText(localization.getString("LABEL_SERVER_PATH") + ":");
        
        log.trace("Creating texts.");
        
        nameText = new Text(add, SWT.BORDER);
        nameText.setLocation(70, 15);
        nameText.setSize(130, 20);
        nameText.setToolTipText(localization.getString("TOOLTIP_SERVER_NAME"));
        nameText.addModifyListener(new NameModifyListener());
        
        serverText = new Text(add, SWT.BORDER);
        serverText.setLocation(70, 45);
        serverText.setSize(190, 20);
        serverText.setToolTipText(localization.getString("TOOLTIP_SERVER"));
        serverText.addModifyListener(new ParametersModifyListener());
        
        portText = new Spinner(add, SWT.BORDER);
        portText.setLocation(70, 75);
        portText.setSize(60, 20);
        portText.setValues(80, 0, 65535, 0, 1, 100);
        portText.setToolTipText(localization.getString("TOOLTIP_PORT"));
        portText.addModifyListener(new ParametersModifyListener());
        
        pathText = new Text(add, SWT.BORDER);
        pathText.setLocation(70, 105);
        pathText.setSize(190, 20);
        pathText.setToolTipText(localization.getString("TOOLTIP_PATH"));
        pathText.addModifyListener(new ParametersModifyListener());
        
        log.trace("Creating buttons.");
        
        testButton = new Button(add, SWT.PUSH);
        testButton.setText(localization.getString("BUTTON_TEST"));
        testButton.setSize(100, 25);
        testButton.setLocation(20, 130);
        testButton.addSelectionListener(new TestSelectionListener());
        
        addButton = new Button(add, SWT.PUSH);
        addButton.setText(localization.getString("BUTTON_ADD"));
        addButton.setSize(80, 25);
        addButton.setLocation(180, 130);
        addButton.addSelectionListener(new AddSelectionListener());
        
        remove = new Button(shell, SWT.PUSH);
        remove.setText(localization.getString("BUTTON_REMOVE"));
        remove.setSize(80, 25);
        remove.setLocation(10, 185);
        remove.addSelectionListener(new RemoveSelectionListener());
        
        final Button close = new Button(shell, SWT.PUSH);
        close.setText(localization.getString("BUTTON_CLOSE"));
        close.setSize(80, 25);
        close.setLocation(405, 185);
        close.addSelectionListener(new CloseSelectionListener());
    }
    
    /** Populates the list with the servers in config. */ 
    private void refreshList()
    {
        log.trace("Filling list.");
        
        final Config config = Config.getInstance();
        
        if (list.getItemCount() > 0)
        {
            list.removeAll();
        }
        
        for (Entry<String, Server> entry : config.getServers().entrySet())
        {
            list.add(entry.getKey());
        }
    }
    
    /** Returns the server name widget.
     * @return The server name widget
     */
    public Text getNameWidget()
    {
        return nameText;
    }
    
    /** Returns the server address widget.
     * @return The server address widget
     */
    public Text getServerWidget()
    {
        return serverText;
    }
    
    /** Returns the port widget.
     * @return The server port widget.
     */
    public Spinner getPortWidget()
    {
        return portText;
    }
    
    /** Returns the path at which to look for the roster.
     * @return Widget of the path to the roster on the server.
     */
    public Text getPathWidget()
    {
        return pathText;
    }
    
    /** Returns the 'test server' button.
     * @return The test server button.
     */
    public Button getTestButton()
    {
        return testButton;
    }
    
    /** Returns the 'add server' button.
     * @return The add server button.
     */
    public Button getAddButton()
    {
        return addButton;
    }
    
    /** Returns the server list.
     * @return The saved servers list
     */
    public List getList()
    {
        return list;
    }
    
    /** Returns the 'remove server' button.
     * @return Button widget
     */
    public Button getRemoveButton()
    {
        return remove;
    }
}
